#include "printf.h"
#include "console.h"
#include "uart.h"
#include "kalloc.h"
#include "vm.h"
#include "assert.h"

void test_printf_basic() {
cprintf("Testing integer: %d\n", 42);
cprintf("Testing negative: %d\n", -123);
cprintf("Testing zero: %d\n", 0);
cprintf("Testing hex: 0x%x\n", 0xABC);
cprintf("Testing string: %s\n","Hello");
cprintf("Testing char: %c\n",'X');
cprintf("Testing percent: %%\n");
}
void test_printf_edge_cases() {
cprintf("INT_MAX: %d\n", 2147483647);
cprintf("INT_MIN: %d\n", -2147483648);
cprintf("NULL string: %s\n", (char*)0);
cprintf("Empty string: %s\n","");
}
void test_ansi_commands() {
cprintf("=== Testing ANSI Commands ===\n");
cprintf("This text will be cleared.\n");
clear_screen(); // 调用清屏函数
goto_xy(5, 10); // 移动光标到第5行第10列
cprintf("Cursor moved to (5,10)");
goto_xy(5,1);
clear_line(); // 清除当前行
cprintf_color(32, "Line was cleared and this is new text.\n");
}

void test_physical_memory(void) {
cprintf("Before testing memory...\n");
// 测试基本分配和释放
kinit();
void *page1 = kalloc();
void *page2 = kalloc();
assert(page1 != page2);
assert(((uint64_t)page1 & 0xFFF) == 0); // 页对齐检查
// 测试数据写入
*(int*)page1 = 0x12345678;
assert(*(int*)page1 == 0x12345678);
// 测试释放和重新分配
kfree(page1);
void *page3 = kalloc();
// page3可能等于page1（取决于分配策略）
kfree(page2);
kfree(page3);
cprintf("After testing memory...\n");
}

void test_pagetable(void) {
cprintf("Before testing pagetable...\n");
pagetable_t pt = create_pagetable();
// 测试基本映射
uint64_t va = 0x1000000;
uint64_t pa = (uint64_t)kalloc();
assert(map_page(pt, va, pa, PTE_R | PTE_W) == 0);
// 测试地址转换
pte_t *pte = walk_lookup(pt, va);
assert(pte != 0 && (*pte & PTE_V));
assert(PTE_PA(*pte) == pa);
// 测试权限位
assert(*pte & PTE_R);
assert(*pte & PTE_W);
assert(!(*pte & PTE_X));
cprintf("After testing pagetable...\n");
}

void test_virtual_memory(void) {
cprintf("Before enabling paging...\n");
// 启用分页
kvminit();
kvminithart();
cprintf("After enabling paging...\n");
// 测试内核代码仍然可执行
cprintf("Testing kernel code execution after paging enabled\n");
// 测试内核数据仍然可访问
static int kernel_test_var = 0x12345678; 
assert(kernel_test_var == 0x12345678);
// 测试设备访问仍然正常
cprintf("Testing device access: console output works\n");
}

void main(void){
	test_physical_memory();
	test_pagetable();
	test_virtual_memory();
}
